package bma.common.langutil.ai;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import bma.common.langutil.ai.common.AICountDownLatch;
import bma.common.langutil.ai.common.AIFunction;
import bma.common.langutil.ai.impl.AIServiceTC1;
import bma.common.langutil.ai.impl.AIStackTC1;
import bma.common.langutil.ai.stack.AIStack;
import bma.common.langutil.ai.vm.AIVM;
import bma.common.langutil.core.ObjectUtil;

public class CountDownLatchUsercaseTC {

	final org.slf4j.Logger log = org.slf4j.LoggerFactory
			.getLogger(CountDownLatchUsercaseTC.class);

	AIVM main;

	@Before
	public void setupMain() {
		main = new AIVM();
		main.installMain();
	}

	@After
	public void closeMain() {
		main.close();
	}

	/**
	 * AICountDownLatch 的用例
	 */
	@Test
	public void countDownLath() throws Exception {
		final AIServiceTC1 s = new AIServiceTC1();
		AIStack<Boolean> stack = new AIStackTC1<Boolean>();

		final AICountDownLatch<Boolean> latch = new AICountDownLatch<Boolean>(5);

		log.info("wait for event");
		latch.waitFor(new AIFunction<Boolean>() {
			@Override
			public boolean apply(AIStack<Boolean> stack) {
				return s.say(stack, "hello world");
			}
		}, stack);

		for (int i = 0; i < 5; i++) {
			main.execute(null, new Runnable() {

				@Override
				public void run() {
					log.info("other thread count down");
					latch.countDown();
				}
			});
		}

		ObjectUtil.waitFor(this, 1000);
	}

	@Test
	public void countDownLatch_timeout() throws Exception {
		final AIServiceTC1 s = new AIServiceTC1();
		AIStack<Boolean> stack = new AIStackTC1<Boolean>();

		final AICountDownLatch<Boolean> latch = new AICountDownLatch<Boolean>(5);

		log.info("wait for event");
		latch.waitFor(new AIFunction<Boolean>() {
			@Override
			public boolean apply(AIStack<Boolean> stack) {
				return s.say(stack, "hello world");
			}
		}, stack, 500);

		ObjectUtil.waitFor(this, 1000);
	}

}
